﻿using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioBairro : IRepositorioBairro
    {
        public Bairro Inserir(Bairro bairro)
        {
            //foreach (Logradouro logradouro in bairro.ListaLogradouros)
            //{
            //    logradouro.Bairro = bairro;
            //}

            GerenciadorBDConfigs.Instance.SessaoAtual().Save(bairro);
            return bairro;
        }

        public Bairro Atualizar(Bairro bairro)
        {
            Bairro tmpBairro = ObterPorId(bairro.BairroId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpBairro.Cidade = bairro.Cidade;
            tmpBairro.Codigo = bairro.Codigo;
            tmpBairro.Descricao = bairro.Descricao;
            tmpBairro.NeturionLog = bairro.NeturionLog;

            //tmpBairro.ListaLogradouros.Clear();
            //foreach (Logradouro logradouro in bairro.ListaLogradouros)
            //{
            //    tmpBairro.AdicionarLogradouro(logradouro);
            //}

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpBairro);
            return tmpBairro;
        }

        public void Excluir(Bairro bairro)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(bairro);
        }

        public IList<Bairro> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Bairro));
            return criteria.List<Bairro>() as List<Bairro>;
        }

        public Bairro ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<Bairro>(id);
        }

        public IList<Bairro> ObterPorDescricao(string descricao)
        {
            ICriteria criteria =
               GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Bairro))
               .Add(Restrictions.Like("Descricao", descricao, MatchMode.Anywhere))
               .AddOrder(Order.Asc("Descricao"));
            return criteria.List<Bairro>() as List<Bairro>;
        }

        public IList<Bairro> ObterTodosBairrosPorCidade(Cidade cidade)
        {
            ICriteria criteria =
                GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof (Bairro))
                .Add(Restrictions.Eq("Cidade", cidade))
                .AddOrder(Order.Asc("Descricao"));
            return criteria.List<Bairro>() as List<Bairro>;
        }

        public int ObterUltimoIdCodigoInteiro()
        {
            string[] literal = new string[] 
                {"a","b","c","d","e","f","g","h","i","j"
                ,"l","m","n","o","p","q","r","s","t","u","v","x","z","y"
                ,"w"};

            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Bairro)).SetMaxResults(1);

            for (int i = 0; i <= literal.Length - 1; i++)
            {
                criteria.Add(Restrictions.Not(Restrictions.Like("Codigo", literal[i], MatchMode.Anywhere)));
            }

            criteria.AddOrder(Order.Desc("BairroId"));


            Bairro bairro = criteria.UniqueResult<Bairro>();
            int ultimoCodigo = bairro != null ? bairro.BairroId : 0;

            return ultimoCodigo;
        }

        public Bairro ObterPorCodigo(string codigo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Bairro))
                .Add(Restrictions.Eq("Codigo", codigo));

            return criteria.UniqueResult<Bairro>() as Bairro;
        }

        public IList<Bairro> ObterPorCodigoeCidade(string codigo, Cidade cidade)
        {
            ICriteria criteria =
                GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Bairro))
                    .Add(Restrictions.Eq("Cidade", cidade))
                    .Add(Restrictions.Or(Restrictions.Eq("Codigo", codigo), Restrictions.Like("Descricao", codigo, MatchMode.Anywhere)))
                    .AddOrder(Order.Asc("Descricao"));

            return criteria.List<Bairro>() as List<Bairro>;
        }
    }
}